﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Mysoft.Common.Exceptions;
using Mysoft.Common.Response;
using Mysoft.Data.CacheManager.IService;
using Mysoft.Domain;
using Mysoft.Domain.Basic;
using System.Net;
using System.Text.Json;

namespace Mysoft.AppStartup.Application
{
    /// <summary>
    /// http请求
    /// </summary>
    public class HandlingMiddleware
    {
        private readonly RequestDelegate _next;  // 用来处理上下文请求  
        private readonly ILogger<HandlingMiddleware> _logger;
        private readonly DomainService<ErrorLogService> _domainService;
        private readonly ICacheService _cacheService;
        public HandlingMiddleware(RequestDelegate next, ILogger<HandlingMiddleware> logger, DomainService<ErrorLogService> domainService, ICacheService cacheService)
        {
            _next = next;
            _logger = logger;
            _domainService = domainService;
        }

        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
             
                await _next(httpContext); //等待http请求是否出现异常
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(httpContext, ex); // 捕获异常
            }
        }


        private async Task HandleExceptionAsync(HttpContext context, Exception exception)
        {
            context.Response.ContentType = "application/json";  // 返回json 类型
            var response = context.Response;

            var errorResponse = new ErrorResponse
            {
                success = false
             };
            // 自定义的异常错误信息类型
            switch (exception)
            {
                case BusinessException ex:
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    break;
                case ApplicationException ex:
                    if (ex.Message.Contains("Invalid token"))
                    {
                        response.StatusCode = (int)HttpStatusCode.Forbidden;
                        break;
                    }
                    response.StatusCode = (int)HttpStatusCode.BadRequest;
                    break;
                case KeyNotFoundException ex:
                    response.StatusCode = (int)HttpStatusCode.NotFound;
                    break;
                default:
                    response.StatusCode = (int)HttpStatusCode.InternalServerError;
                    break;
            }
            errorResponse.code = response.StatusCode;
            errorResponse.message = exception.Message;

            _logger.LogError(exception.Message);
            _domainService.Instance.Write(exception.Message, exception.StackTrace);
            var result = JsonSerializer.Serialize(errorResponse);
            await context.Response.WriteAsync(result);
        }
    }
}
